const mysql = require('../db/mysql57');
const minio = require('../db/minio');
const { wx } = require('../util/server_config');

const config = require('../config');

const userDao = {
    async getAvater(id) {
        let sql = `select * from PublicImg where id = ? and browser = ? LIMIT 1`;
        let data = [ id, config.minio.avaterBrower ];
        let result = await mysql.sqlExec(sql, data);
        if (result.length == 0) {
            return { success: false, msg: '该图片不存在' };
        } else {
            let url = await minio.getDownloadUrl(config.minio.avaterBrower, result[0].uri, config.minio.downloadUrlEnableTime);
            if (!url.success) {
                return { success: false, msg: '获取图片失败' };
            }
            return { success: true, data: url.url };
        }
    },
    getUserInfo(id) {
        let sql = `select
                u.id as id,
                u.username as name,
                u.avaterId as avaterId,
                u.gender as gender,
                u.phone as phone,
                u.email as email,
                u.bio as bio,
                u.school as school,
                u.major as major,
                u.grade as grade,
                u.balance as balance,
                u.points as points,
                u.level as level
            from
                User as u
            where u.id = ? Limit 1`;
        let data = [ id ];
        return mysql.sqlExec(sql, data);
    },
    setUserInfo(uid, userInfo) {
        let update_list = [];
        let data = [];
        if (userInfo.username) {
            update_list.push('username = ?');
            data.push(userInfo.username);
        }
        if (userInfo.gender) {
            update_list.push('gender = ?');
            data.push(userInfo.gender);
        }
        if (userInfo.phone) {
            update_list.push('phone = ?');
            data.push(userInfo.phone);
        }
        if (userInfo.email) {
            update_list.push('email = ?');
            data.push(userInfo.email);
        }
        if (userInfo.bio) {
            update_list.push('bio = ?');
            data.push(userInfo.bio);
        }
        if (userInfo.school) {
            update_list.push('school = ?');
            data.push(userInfo.school);
        }
        if (userInfo.major) {
            update_list.push('major = ?');
            data.push(userInfo.major);
        }
        if (userInfo.grade) {
            update_list.push('grade = ?');
            data.push(userInfo.grade);
        }
        data.push(uid);
        let update_str = update_list.join(', ');
        let sql = `UPDATE User SET ${ update_str } WHERE id = ?`;
        return mysql.sqlExec(sql, data);
    },
    async setAvatar(uid, avatar) {
        // 尝试开启事务
        let sql;
        let data;
        let connection;
        let result;
        let browser = config.minio.avaterBrower;
        let uri = '';
        let avaterId;
        let return_data = {};
        // 开启事务
        try {
            connection = await mysql.startTransaction();
        } catch (error) {
            throw error;
        }
        // 往 PublicImg 表中插入数据
        try {
            let sql = `insert into PublicImg (browser, uri, status) VALUES (?, ?, ?)`;
            let data = [ browser, uri, '待上传' ];
            result = await mysql.sqlExecInTransaction(connection, sql, data);
            avaterId = result.insertId;
            uri = `${avaterId}.jpg`;
            return_data.avaterId = avaterId;
        } catch (error) {
            await mysql.rollbackTransaction(connection);
            throw error;
        }
        // 更新 mysql 数据库中 图片的上传状态
        try {
            sql = `update PublicImg set status = ?, uri = ? where id = ?`;
            data = [ '已完成', uri, avaterId ];
            await mysql.sqlExecInTransaction(connection, sql, data);
            sql = `update User set avaterId = ? where id = ?`;
            data = [ avaterId, uid ];
            result = await mysql.sqlExecInTransaction(connection, sql, data);
            return_data.affectedRows = result.affectedRows;
        } catch (err) {
            await mysql.rollbackTransaction(connection);
            throw err;
        }
        // 记录用户的新头像到用户历史头像表里
        try {
            sql = `INSERT INTO HistoryUserAvater (uid, imgId) VALUES (?, ?)`;
            data = [ uid, avaterId ];
            await mysql.sqlExecInTransaction(connection, sql, data);
        } catch (err) {
            await mysql.rollbackTransaction(connection);
            throw err;
        }
        // 往 MinIO 中上传图片（这个操作应该要封装到 minio 驱动里，后续修改）
        try {
            let buffer = avatar.buffer;
            uri = `${ avaterId }.jpg`;
            await new Promise((resolve, reject) => {
                minio.minio.putObject(browser, uri, buffer, buffer.length, async function (err, etag) {
                    if (err) {
                        reject(err);
                        return ;
                    } else {
                        resolve(true);
                    }
                });
            });
        } catch (err) {
            await mysql.rollbackTransaction(connection);
            throw err;
        }
        // 提交事务
        try {
            mysql.commitTransaction(connection);
        } catch (error) {
            await mysql.rollbackTransaction(connection);
            throw error;
        }
        // 返回数据
        return return_data;
    }
};

module.exports = userDao;
